resource = other_config.get("resource", 0)
port = other_config.get("port", 0)
+ node = other_config.get("node", 0)
xendom.domain_migrate(xeninfo.getDomid(), destination_url,
- bool(live), resource, port)
+ bool(live), resource, port, node)
return xen_api_success_void()
def VM_save(self, _, vm_ref, dest, checkpoint):
from xen.xend.XendLogging import log
from xen.xend.XendConfig import XendConfig
from xen.xend.XendConstants import *
+from xen.xend import XendNode
SIGNATURE = "LinuxGuestRecord"
QEMU_SIGNATURE = "QemuDeviceModelRecord"
return buf
-def save(fd, dominfo, network, live, dst, checkpoint=False):
+def insert_after(list, pred, value):
+ for i,k in enumerate(list):
+ if type(k) == type([]):
+ if k[0] == pred:
+ list.insert (i+1, value)
+ return
+
+
+def save(fd, dominfo, network, live, dst, checkpoint=False, node=-1):
write_exact(fd, SIGNATURE, "could not write guest state file: signature")
- config = sxp.to_string(dominfo.sxpr())
+ sxprep = dominfo.sxpr()
+
+ if node > -1:
+ insert_after(sxprep,'vcpus',['node', str(node)])
+
+ config = sxp.to_string(sxprep)
domain_name = dominfo.getName()
# Rename the domain temporarily, so that we don't get a name clash if this
else:
dominfo = xd.restore_(vmconfig)
+ # repin domain vcpus if a target node number was specified
+ # this is done prior to memory allocation to aide in memory
+ # distribution for NUMA systems.
+ nodenr = -1
+ for i,l in enumerate(vmconfig):
+ if type(l) == type([]):
+ if l[0] == 'node':
+ nodenr = int(l[1])
+
+ if nodenr >= 0:
+ node_to_cpu = XendNode.instance().xc.physinfo()['node_to_cpu']
+ if nodenr < len(node_to_cpu):
+ for v in range(0, dominfo.info['VCPUs_max']):
+ xc.vcpu_setaffinity(dominfo.domid, v, node_to_cpu[nodenr])
+
store_port = dominfo.getStorePort()
console_port = dominfo.getConsolePort()
return val
- def domain_migrate(self, domid, dst, live=False, resource=0, port=0):
+ def domain_migrate(self, domid, dst, live=False, resource=0, port=0, node=-1):
"""Start domain migration.
@param domid: Domain ID or Name
@type live: bool
@keyword resource: not used??
@rtype: None
+ @keyword node: use node number for target
+ @rtype: int
@raise XendError: Failed to migrate
@raise XendInvalidDomain: Domain is not valid
"""
sock.send("receive\n")
sock.recv(80)
- XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst)
+ XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst, node=node)
sock.close()
def domain_save(self, domid, dst, checkpoint=False):
fn=set_int, default=0,
use="Use specified port for migration.")
+gopts.opt('node', short='n', val='nodenum',
+ fn=set_int, default=-1,
+ use="Use specified NUMA node on target.")
+
gopts.opt('resource', short='r', val='MBIT',
fn=set_int, default=0,
use="Set level of resource usage for migration.")
vm_ref = get_single_vm(dom)
other_config = {
"port": opts.vals.port,
- "resource": opts.vals.resource
+ "resource": opts.vals.resource,
+ "node": opts.vals.node
}
server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
other_config)
else:
server.xend.domain.migrate(dom, dst, opts.vals.live,
opts.vals.resource,
- opts.vals.port)
+ opts.vals.port,
+ opts.vals.node)